package cn.amossun.starter.event.handler;

import cn.hutool.core.util.StrUtil;
import cn.amossun.starter.event.annoation.Argument;
import cn.amossun.starter.event.annoation.EventPublisher;
import cn.amossun.starter.event.common.Constants;
import cn.amossun.starter.event.exception.EventConfigException;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public interface EventMessagePublisher {

    default String getRoutingKey(EventPublisher eventPublisher){
        if(eventPublisher.binding() != null && eventPublisher.binding().exchange() != null) {
            return eventPublisher.binding().key();
        }

        return eventPublisher.key();
    }

    default Map<String, Object> getArguments(Argument[] arguments) {
        Map<String, Object> argumentsMap = new HashMap<>(arguments.length);
        Arrays.asList(arguments).stream().forEach(source -> argumentsMap.put(source.key(), source.value()));
        return argumentsMap;
    }

    default Map<String, Object> getArgumentsMap(EventPublisher eventPublisher){
        Argument[] arguments = eventPublisher.binding() != null ? eventPublisher.binding().arguments() :
                (eventPublisher.exchange() != null ? eventPublisher.exchange().arguments() : eventPublisher.arguments());

        Map<String, Object> argumentsMap = new HashMap<>(arguments.length);
        Arrays.asList(arguments).stream().forEach(source -> argumentsMap.put(source.key(), source.value()));
        return argumentsMap;
    }


    default String getExchangeName(EventPublisher eventPublisher){
        if(eventPublisher.binding() != null && eventPublisher.binding().exchange() != null) {
            return eventPublisher.binding().exchange().name();
        }

        if(eventPublisher.exchange() != null){
            return eventPublisher.exchange().name();
        }

        return getDefaultExchangeName(eventPublisher.defaultTopicExchange(), eventPublisher.defaultHeadersExchange());
    }

    default String getDefaultExchangeName(boolean defaultTopicExchange, boolean defaultHeadersExchange) {
        String defaultExchangeName = defaultTopicExchange ? Constants.EVENT_TOPIC_EXCHANGE :
                (defaultHeadersExchange ? Constants.EVENT_HEADER_EXCHANGE : null);

        if(StrUtil.isEmpty(defaultExchangeName)) {
            throw new EventConfigException("missing default 'Exchange' config");
        }
        return defaultExchangeName;
    }

}
